/*
 * 人人信用管理有限公司版权所有.
 * 
 * @Description:
 * 
 * @author: liyuliang
 * 
 * @date: 20 Apr 2017 10:44:16 am
 * 
 * 注意：本内容仅限于人人信用管理有限公司内部传阅，禁止外泄以及用于其他的商业目的.
 */

package com.rrx360.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

  private static ThreadLocal<DateFormat> yyyyMMdd = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyyMMdd");
    }
  };

  private static ThreadLocal<DateFormat> yyyy_MM_dd = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd");
    }
  };

  private static ThreadLocal<DateFormat> yyyy_MM_dd_HHmmss = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
  };

  private static ThreadLocal<DateFormat> yyyyMMddHHmmss = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyyMMddHHmmss");
    }
  };

  public static String formatYyyyMMdd(Date date) {
    if (date == null) {
      return null;
    }
    return yyyyMMdd.get().format(date);
  }

  public static String formatYyyy_MM_dd_HHmmss(Date date) {
    if (date == null) {
      return null;
    }
    return yyyy_MM_dd_HHmmss.get().format(date);
  }

  public static String formatYyyyMMddHHmmss(Date date) {
    if (date == null) {
      return null;
    }
    return yyyyMMddHHmmss.get().format(date);
  }

  public static String formatYyyy_MM_dd(Date date) {
    if (date == null) {
      return null;
    }
    return yyyy_MM_dd.get().format(date);
  }

  public static Date parseYyyy_MM_dd(String s) {
    try {
      return yyyy_MM_dd.get().parse(s);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }

  public static Date parseYyyy_MM_ddHHmmss(String s) {
    try {
      return yyyy_MM_dd_HHmmss.get().parse(s);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }

  public static Date parseYyyyMMddHHmmss(String s) {
    try {
      return yyyyMMddHHmmss.get().parse(s);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }

  public static Date parseYyyyMMdd(String s) {
    try {
      return yyyyMMdd.get().parse(s);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }

  public static int getCurrentMonth() {
    return getMonth(new Date());
  }

  public static int getDayNumOfMonth(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
  }

  public static int getDayNumOfMonth(Integer year, Integer month) {
    if (month == null) {
      return 31;
    }
    if (year == null) {
      if (month == 2) {
        return 29;
      } else {
        year = getCurrentYear();
      }
    }
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy/MM");
    try {
      cal.setTime(simpleDate.parse(year + "/" + month));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    return days;
  }

  public static int getCurrentYear() {
    return getYear(new Date());
  }

  public static int getCurrentDay() {
    return getDay(new Date());
  }

  public static Date lastYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(date.getTime());
    calendar.add(Calendar.YEAR, -1);
    return calendar.getTime();
  }

  public static int getYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(date.getTime());
    int currenYear = calendar.get(Calendar.YEAR);
    return currenYear;
  }

  public static int getMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(date.getTime());
    int currenMonth = calendar.get(Calendar.MONTH);
    return currenMonth + 1;
  }

  public static int getDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(date.getTime());
    int currenDay = calendar.get(Calendar.DAY_OF_MONTH);
    return currenDay;
  }

  public static int getAge(Date birthday) {
    return getYear(new Date()) - getYear(birthday) + 1;

  }

  /**
   * t1 <= t2
   * 
   * @param t1
   * @param t2
   * @return
   */
  public static int daysBetween(Date t1, Date t2) {
    return (int) ((t2.getTime() - t1.getTime()) / (24 * 3600 * 1000));
  }

  public static Date lastDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
    return calendar.getTime();
  }

  public static Date nextDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
    return calendar.getTime();
  }

  public static Date firstDayOfLastWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
      calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - 1);
    }
    calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - 1);
    calendar.set(Calendar.DAY_OF_WEEK, 2);
    return calendar.getTime();
  }

  public static Date firstDayOfCurrentWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
      calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - 1);
    }
    calendar.set(Calendar.DAY_OF_WEEK, 2);
    return calendar.getTime();

  }

  public static Date firstDayOfNextWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
      calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - 1);
    }
    calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) + 1);
    calendar.set(Calendar.DAY_OF_WEEK, 2);
    return calendar.getTime();
  }

  public static Date firstDayOfLastMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    return calendar.getTime();
  }

  public static Date firstDayOfCurrentMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    return calendar.getTime();
  }

  public static Date firstDayOfNextMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    return calendar.getTime();
  }

  public static Date firstDayOfLastYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
    calendar.set(Calendar.DAY_OF_YEAR, 1);
    return calendar.getTime();
  }

  public static Date firstDayOfCurrentYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DAY_OF_YEAR, 1);
    return calendar.getTime();
  }

  public static Date firstDayOfNextYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 1);
    calendar.set(Calendar.DAY_OF_YEAR, 1);
    return calendar.getTime();
  }

}
